/*
 *
 * Copyright (C) 2012 Walter Lütgenau
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package offset.nodes.server.html.controller;

import offset.nodes.server.html.model.HtmlSubstituter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import offset.nodes.Constants;
import offset.nodes.server.binary.controller.BinaryAttribute;
import offset.nodes.server.controller.AuthenticatingAction;
import offset.nodes.server.dispatch.controller.DispatchAttribute;
import offset.nodes.server.controller.EditorAttribute;
import offset.nodes.server.html.model.HttpContext;
import offset.nodes.server.html.model.PageModel;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
 *
 * @author Walter Lütgenau
 */
public class HtmlAction extends AuthenticatingAction {
    public static final String EMPTY_PAGE = "<p></p>";
    
    /** Creates a new instance of DocumentationAction */
    public HtmlAction() {
    }
    
    protected boolean isHTML( String path ) {
        if ( path.endsWith("html") || path.endsWith("htm"))
            return true;
        if ( path.indexOf("/") >= 0) {
            String lastComponent = path.substring(path.lastIndexOf("/"));
            if ( lastComponent.indexOf(".") < 0)
                return true;
        }
        
        return false;
    }

    /**
     * Substitute internal hyperlinks with an href of the form "/a/b?reference=....&propertyName=name with the value of
     * the property of the referenced node.
     *
     * @param session
     * @param input
     * @return
     * @throws IOException
     * @throws RepositoryException
     */
    protected InputStream substituteHyperlinksAndComponents(Session session, InputStream input, HttpContext context) throws IOException, RepositoryException, Exception {
        byte[] buf = new byte[input.available()];
        input.read(buf);

        String content = new String(buf);

        HtmlSubstituter substituter = new HtmlSubstituter(session);
        String result = substituter.substituteHyperlinks(content);
        result = substituter.substituteComponentPage(result, context);

        return new ByteArrayInputStream(result.getBytes());
    }
    
    public ActionForward process(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
        HtmlForm pageForm = (HtmlForm) form;
        
        // handle URL actions
        DispatchAttribute dispatchInfo = (DispatchAttribute) request.getAttribute(DispatchAttribute.ATT_DISPATCH);
        
        if ( dispatchInfo.getNode() == null ) {
           String path = dispatchInfo.getPath();
           if ( !isHTML( path ) ) { // unknown CSS or image
                request.setAttribute(BinaryAttribute.ATT_DOWNLOAD, new BinaryAttribute() );
                return mapping.findForward("binary");                
            }       
           // else fall through to browser. This will create an empty page in HtmlBean.
        }

        PageModel model = new PageModel(getRepositorySession(request));
        BinaryAttribute downloadAttribute = model.getDownloadInfo(dispatchInfo.getNode());
        if (downloadAttribute == null) {
            downloadAttribute = new BinaryAttribute();
            downloadAttribute.setInput(new ByteArrayInputStream(EMPTY_PAGE.getBytes()));
        }
        
        // determine forward now. The component substitution may change the form.
        ActionForward forward;
        if (request.getAttribute(EditorAttribute.ATT_EDITOR) != null)
            forward = mapping.findForward("edit");
        else if ( pageForm.getMode().equals(Constants.PARVALUE_APPLET)) // todo: find a better way to distinguish between applet and browser request
            forward = mapping.findForward("applet");
        else if (pageForm.getMode().equals(Constants.PARVALUE_PRINT))
            forward = mapping.findForward("print");
        else
            forward = mapping.findForward( "browser");

        if (!pageForm.getMode().equals(Constants.PARVALUE_APPLET)) {
            downloadAttribute.setInput(substituteHyperlinksAndComponents(getRepositorySession(request), 
                    downloadAttribute.getInput(),
                    new HttpContext(getServlet(), request, response)));
        }

        HtmlAttribute htmlAttribute = new HtmlAttribute();
        htmlAttribute.setPath(dispatchInfo.getPath());
        htmlAttribute.setNode(dispatchInfo.getNode());
        htmlAttribute.setDownloadAttribute(downloadAttribute);

        request.setAttribute(htmlAttribute.getId(), htmlAttribute);

        
        return forward;
    }
    
    
}
